#include "comm/my_log.h"
#include "comm/my_spinlock.h"

#include <pthread.h>

void test_spinlock() {
    my_spinlock_t lock;
    my_spinlock_init(&lock);

    my_spinlock_lock(&lock);
    my_spinlock_unlock(&lock);

    my_spinlock_lock(&lock);
    if (my_spinlock_trylock(&lock)) {
        MY_LOG_FATAL("except false, but got true");
    }
    my_spinlock_unlock(&lock);

    if (!my_spinlock_trylock(&lock)) {
        MY_LOG_FATAL("except true, but got false");
    }

    my_spinlock_unlock(&lock);
}

#define N 10
#define M 1000000
my_spinlock_t g_lock;
int g_i = 0;

void *do_test(void *arg) {
    (void)arg;

    for (int i = 0; i < M; i++) {
        my_spinlock_lock(&g_lock);
        g_i++;
        my_spinlock_unlock(&g_lock);
    }

    return NULL;
}

void test_mult_thread_lock() {
    my_spinlock_init(&g_lock);
    pthread_t tids[N];

    for (int i = 0; i < N; i++) {
        pthread_t tid;
        pthread_create(&tid, NULL, do_test, NULL);
        tids[i] = tid;
    }

    for (int i = 0; i < N; i++) {
        pthread_join(tids[i], NULL);
    }

    if (g_i != N*M) {
        MY_LOG_FATAL("except %d, but got %d", N*M, g_i);
    }
}

int main()
{
    test_spinlock();
    test_mult_thread_lock();

    MY_LOG_DEBUG("test pass");
}